Popular Searches
Popular Course Categories
Popular Courses

Managing Activity State and Application Lifecycle Events

Managing Activity State and Application Lifecycle Events

Android Application Components and Lifecycle

Managing Activity State and Application Lifecycle Events

Course: Android App Development

Topic: Managing Activity State and Application Lifecycle Events

Course Link: Android App Development Course

Demo Link: Register for a Course Demo

JustAcademy Homepage: Visit JustAcademy


1. Introduction

Activity state management and application lifecycle handling are essential concepts in Android development. An Activity represents a screen that allows users to interact with an application. During its lifetime, an Activity can be created, displayed, paused, stopped, restarted, or destroyed depending on user actions and operating-system decisions.

For example, a user might open a shopping application, search for a product, rotate the device, receive a phone call, or switch to another application. Android manages the Activity lifecycle during these events. Developers must ensure that the application responds correctly, preserves important user input, manages resources efficiently, and restores the screen when necessary.

Android provides lifecycle callback methods such as onCreate(), onStart(), onResume(), onPause(), onStop(), onRestart(), and onDestroy(). These callbacks help developers control initialization, visibility-dependent operations, temporary state restoration, and cleanup.

2. Learning Objectives

  • Understand the Android Activity lifecycle and its callback methods.
  • Identify the difference between Activity state and application process state.
  • Learn when to initialize, pause, resume, and release application resources.
  • Save and restore lightweight UI state using a Bundle.
  • Understand the role of ViewModel in managing screen-related data.
  • Handle configuration changes such as screen rotation.
  • Understand system-initiated process death and state restoration.
  • Apply lifecycle-aware development practices to reduce memory leaks.
  • Test Activity lifecycle behavior using Android Studio and Logcat.

3. What Is the Android Activity Lifecycle?

The Android Activity lifecycle describes the different states an Activity passes through from creation to destruction. Android invokes lifecycle callback methods when an Activity changes state so that the application can respond appropriately.

Consider a music application. When the user opens the player screen, the Activity is created and becomes interactive. If the user opens another screen, the player Activity may become paused or stopped. When the user returns, the application should restore the relevant screen information and resume appropriate operations.

Why Is Lifecycle Management Important?

  • Better user experience: Preserves useful screen information and user progress.
  • Resource efficiency: Helps manage cameras, sensors, listeners, and other resources.
  • Performance: Prevents unnecessary operations when a screen is hidden.
  • Reliability: Helps the application handle configuration changes and system interruptions.
  • Battery efficiency: Reduces unnecessary background processing.
  • Data protection: Helps prevent the loss of important user-entered information.

4. Main Activity Lifecycle Callback Methods

Method Purpose Common Usage
onCreate() Called when a new Activity instance is created. Initialize the screen, views, and required components.
onStart() Called when the Activity becomes visible. Prepare UI-related operations that require visibility.
onResume() Called when the Activity enters the resumed state. Resume foreground interactions and appropriate resources.
onPause() Called when the Activity loses its resumed state. Pause foreground-only work and interactions.
onStop() Called when the Activity is no longer visible. Stop visibility-dependent work and release unneeded resources.
onRestart() Called when a stopped Activity is about to start again. Prepare the Activity to become visible again.
onDestroy() Called before an Activity instance is destroyed during normal lifecycle processing. Perform appropriate final cleanup for the instance.

Developers do not need to override every lifecycle method. They should implement the callbacks required by their application and call the superclass implementation when overriding them.

5. Understanding Lifecycle Methods in Detail

5.1 onCreate()

The onCreate() method is called when Android creates a new Activity instance. It is generally used to perform initial setup and prepare the screen for the user.

Common responsibilities include:

  • Calling super.onCreate(savedInstanceState).
  • Setting the layout using setContentView() in a traditional View-based application.
  • Initializing view references and adapters.
  • Obtaining a ViewModel when required.
  • Restoring saved values from the provided Bundle.
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Initialize screen components.
    }
}

The Activity can be recreated after a configuration change. Therefore, onCreate() may execute multiple times during a user's session.

5.2 onStart()

The onStart() method runs when the Activity becomes visible. The Activity is moving toward the foreground, but it is not necessarily the currently focused screen.

It can be used for operations that need to be active while the screen is visible, such as registering a listener that supplies information for the visible UI.

override fun onStart() {
    super.onStart()
    // Register visibility-dependent observers if needed.
}

5.3 onResume()

The onResume() method runs when the Activity enters the resumed state. The Activity is generally in the foreground and ready for user interaction.

Examples of appropriate operations include resuming a paused animation, enabling foreground-only interactions, or restarting a camera preview when the application is allowed to use the camera.

override fun onResume() {
    super.onResume()
    // Resume work that requires an active foreground screen.
}

Avoid lengthy database operations, file processing, and network requests on the main thread. Such work can make the interface unresponsive.

5.4 onPause()

The onPause() method runs when the Activity loses its resumed state. This may happen when another Activity takes focus, a system interface interrupts the application, or the user navigates away.

Use this callback to pause operations that should not continue while the Activity is not resumed. For example, a game may pause an animation or a camera screen may temporarily stop its preview.

override fun onPause() {
    // Pause foreground-only operations.
    super.onPause()
}

Important: An Activity in the paused state may still be partially visible, such as in certain multi-window or translucent-window situations. Keep this callback short and do not rely on it as the only opportunity to save important data.

5.5 onStop()

The onStop() method runs when the Activity is no longer visible to the user. It is suitable for stopping operations that are needed only while the screen is visible.

Typical responsibilities include stopping UI refresh tasks, unregistering visibility-dependent listeners, and releasing resources that are not needed while the Activity is hidden.

override fun onStop() {
    // Stop work that is unnecessary while the screen is hidden.
    super.onStop()
}

If important data needs to be written to persistent storage, use a reliable save strategy. Do not depend exclusively on the Activity's final lifecycle callback.

5.6 onRestart()

The onRestart() method is called when a stopped Activity is about to start again. Android normally follows it with onStart() and onResume().

override fun onRestart() {
    super.onRestart()
    // Prepare for the Activity to become visible again.
}

5.7 onDestroy()

The onDestroy() method is called before an Activity instance is destroyed through normal lifecycle processing. It may occur when the Activity is finishing or when Android is recreating it after a configuration change.

override fun onDestroy() {
    // Release remaining instance-specific resources if required.
    super.onDestroy()
}

Android may terminate an application's process without calling onDestroy() for its Activities. Consequently, this callback must not be the only place where important data is saved.

6. Typical Activity Lifecycle Flow

When an Activity Opens

onCreate()
    |
onStart()
    |
onResume()
    |
Activity is resumed and interactive

When an Activity Becomes Fully Hidden

onPause()
    |
onStop()

When a Stopped Activity Becomes Visible Again

onRestart()
    |
onStart()
    |
onResume()

When an Activity Is Destroyed

The sequence depends on why the Activity is being destroyed. For example, a configuration change commonly causes the existing Activity to go through the necessary stopping and destruction callbacks before a new instance is created. The new instance then follows its creation and startup sequence.

These sequences are typical patterns rather than a guarantee that every user action produces exactly the same callbacks in every situation.

7. What Is Activity State?

Activity state is the information required to represent the current screen or continue the user's task. It can include user input, the selected tab, the current question in a quiz, the scroll position, a search query, or the current step in a form.

For example, a registration screen may need to preserve:

  • The name entered by the user.
  • The selected country or state.
  • The current step of the registration process.
  • The selected options in a form.
  • The user's current search query.

When Android recreates an Activity, the original instance's ordinary properties are not automatically copied into the new instance. State must be restored using appropriate UI restoration, saved-state mechanisms, a ViewModel, or persistent storage.

8. Types of State Storage

Storage Method Best Use Configuration Change Process Death
Activity properties Temporary data belonging to one Activity instance. Not preserved automatically. Not preserved.
ViewModel Screen-related data and logic. Normally preserved for the same ViewModel scope. Not preserved by itself.
Saved instance state Bundle Small transient UI values. Can be restored. Can be restored after system-initiated recreation when saved state is available.
SavedStateHandle Small state associated with a ViewModel. Can be restored. Can restore supported saved values after system-initiated process recreation.
Local persistent storage Important app data, settings, and records. Survives. Survives, assuming successful storage and no deletion.
Remote backend Account data and information shared across sessions or devices. Can be retrieved again. Can be retrieved again when available and successfully stored remotely.

The appropriate storage method depends on the importance, size, and expected lifetime of the data. A Bundle is intended for small, lightweight values rather than large objects or complete datasets.

9. Saving Activity State with onSaveInstanceState()

The onSaveInstanceState() callback allows an Activity to save small amounts of transient state in a Bundle. Android can supply this state when recreating the Activity after a configuration change or certain system-initiated destruction events.

For example, a quiz application can preserve the current question number and score.

class QuizActivity : AppCompatActivity() {

    private var currentQuestion = 0
    private var score = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_quiz)

        currentQuestion = savedInstanceState?.getInt(KEY_QUESTION) ?: 0
        score = savedInstanceState?.getInt(KEY_SCORE) ?: 0

        updateQuestionUI()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        outState.putInt(KEY_QUESTION, currentQuestion)
        outState.putInt(KEY_SCORE, score)
        super.onSaveInstanceState(outState)
    }

    private fun updateQuestionUI() {
        // Update the interface using currentQuestion and score.
    }

    companion object {
        private const val KEY_QUESTION = "current_question"
        private const val KEY_SCORE = "score"
    }
}

How the Example Works

  1. The Activity checks whether saved state is available when it starts.
  2. If saved values exist, it restores the question number and score.
  3. If saved values do not exist, the default values are used.
  4. When Android requests state saving, the current values are added to the Bundle.
  5. The screen is updated using the restored state.

Always call super.onSaveInstanceState(outState) so Android can save the default view hierarchy state. This callback is not guaranteed to run when a user explicitly finishes an Activity.

10. Restoring State with onRestoreInstanceState()

The onRestoreInstanceState() callback is another place to restore saved Activity state. Android calls it after onStart() when saved instance state is available. It can be helpful when restoration depends on views that have already been restored.

private var selectedTab = 0

override fun onSaveInstanceState(outState: Bundle) {
    outState.putInt("selected_tab", selectedTab)
    super.onSaveInstanceState(outState)
}

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)

    selectedTab = savedInstanceState.getInt("selected_tab", 0)
    // Update the selected tab in the interface.
}

State can also be restored in onCreate(). Choose a consistent strategy for each value so that restored values are not accidentally overwritten by default initialization.

11. Managing State with ViewModel

A ViewModel is an Android architecture component used to store screen-related data and business logic. It can retain that data across configuration changes while its ViewModel scope remains alive.

For example, a counter screen can use a ViewModel so its count remains available when the Activity is recreated because of device rotation.

import androidx.lifecycle.ViewModel

class CounterViewModel : ViewModel() {

    var count: Int = 0
        private set

    fun increment() {
        count++
    }
}

Use the ViewModel from an Activity:

import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity

class CounterActivity : AppCompatActivity() {

    private val viewModel: CounterViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_counter)

        val countText = findViewById<TextView>(R.id.countText)
        val incrementButton = findViewById<Button>(R.id.incrementButton)

        fun renderCount() {
            countText.text = viewModel.count.toString()
        }

        incrementButton.setOnClickListener {
            viewModel.increment()
            renderCount()
        }

        renderCount()
    }
}

This example demonstrates in-memory retention across configuration changes. It does not preserve the count after process death. For that requirement, use saved-state APIs such as SavedStateHandle for suitable lightweight values and persistent storage for information that must remain available later.

12. Understanding Configuration Changes

A configuration change occurs when certain device or application settings change. Examples include screen rotation, changes in screen size, multi-window mode, and some locale or display configuration changes.

By default, many configuration changes cause Android to recreate an Activity. This allows the application to reload resources and layouts appropriate for the new configuration.

Example: Screen Rotation

Imagine a user entering a long message into a form. When the device rotates, Android may destroy the current Activity and create a new instance. If the message is stored only in an ordinary Activity property, the value can be lost.

To manage this correctly:

  • Use view-state restoration for supported UI components.
  • Use a ViewModel for screen data that should survive configuration changes.
  • Use saved instance state for small custom values that need restoration.
  • Use persistent storage for important information that must survive beyond the current Activity or process.

13. Handling Application Process Death

Android may terminate an application's process when system resources are needed. A process containing only stopped Activities can be more vulnerable to termination than one currently serving the foreground user experience.

If the process is terminated, its Activity objects, ordinary variables, and in-memory ViewModels are lost. When the user returns, Android may create a new process and recreate the screen.

To handle process death effectively:

  • Save small transient UI values through saved instance state.
  • Use SavedStateHandle for appropriate ViewModel state.
  • Store important records in a database, DataStore, files, or a backend.
  • Reload information from its source when appropriate.
  • Design network and database operations to handle retries and interruptions.

Do not treat a ViewModel as permanent storage. It survives certain Activity recreation events, but it does not automatically survive process death.

14. Managing Resources During Lifecycle Events

Android applications may use cameras, location updates, sensors, animations, media players, and listeners. Developers must decide when these resources should be active and when they should be paused or released.

Resource Lifecycle Management Strategy
Camera preview Start or resume when appropriate for the foreground screen and release when no longer required.
UI animation Pause while the relevant screen is not active and resume when appropriate.
Sensor listener Register only while sensor data is required and unregister when it is no longer needed.
Screen-specific observer Prefer lifecycle-aware observation APIs.
Database operations Use asynchronous operations and appropriate repository patterns rather than blocking the main thread.
Important user edits Save at meaningful points instead of relying solely on Activity destruction.

The correct lifecycle boundary depends on the task. Some operations should run only while the Activity is resumed, while others need to remain active as long as the screen is visible.

15. Example: Logging Activity Lifecycle Events

Lifecycle logging is a practical way to understand how Android responds to navigation, rotation, and backgrounding. The following Kotlin example writes callback names to Logcat.

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity

class LifecycleActivity : AppCompatActivity() {

    private val tag = "LifecycleActivity"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.d(tag, "onCreate")
    }

    override fun onStart() {
        super.onStart()
        Log.d(tag, "onStart")
    }

    override fun onResume() {
        super.onResume()
        Log.d(tag, "onResume")
    }

    override fun onPause() {
        Log.d(tag, "onPause")
        super.onPause()
    }

    override fun onStop() {
        Log.d(tag, "onStop")
        super.onStop()
    }

    override fun onRestart() {
        super.onRestart()
        Log.d(tag, "onRestart")
    }

    override fun onDestroy() {
        Log.d(tag, "onDestroy")
        super.onDestroy()
    }
}

Testing the Example

  1. Run the application in Android Studio.
  2. Open Logcat and filter the output using LifecycleActivity.
  3. Open the Activity and observe the initial callbacks.
  4. Press Home or open another application, then observe the transition.
  5. Return to the Activity and observe the restart sequence if it was stopped.
  6. Rotate the device and observe whether Android recreates the Activity.

The precise sequence depends on the action, Android version, and window configuration.

16. Common Lifecycle Mistakes

Mistake Possible Consequence Recommended Solution
Keeping all data in Activity properties State may disappear after Activity recreation. Use a ViewModel, saved state, or persistent storage as appropriate.
Saving important data only in onDestroy() The callback may not run during process termination. Save data at appropriate points and use durable storage.
Performing lengthy work in onPause() May delay transitions to another Activity. Keep the callback short and move expensive work off the main thread.
Failing to unregister listeners Can cause duplicate callbacks, resource waste, or memory leaks. Match registration and cleanup to the resource's lifecycle requirements.
Putting large data into a Bundle Can cause serialization overhead or transaction-size problems. Store large data separately and save a small identifier when possible.
Assuming onPause() means invisible Work may stop even though the Activity remains partly visible. Use the appropriate callback based on whether the Activity is resumed or visible.
Starting duplicate work on every resume Repeated requests or listeners may accumulate. Track resource ownership and use lifecycle-aware APIs.

17. Best Practices for Lifecycle Management

  • Keep lifecycle callbacks concise.
  • Initialize Activity-specific components in onCreate().
  • Use onResume() and onPause() for foreground interaction work.
  • Use onStart() and onStop() for visibility-dependent work.
  • Use ViewModels to separate screen state from Activity instance details.
  • Use saved instance state for small, transient values that need restoration.
  • Use persistent storage for important data that must survive process death.
  • Prefer lifecycle-aware observers and coroutine collection patterns.
  • Avoid long-lived references to Activity objects or their views.
  • Test screen rotation, backgrounding, navigation, and process recreation.
  • Do not assume that an app process will remain in memory while the app is in the background.

18. Practical Exercise: Activity State Restoration App

Project Objective

Create an Android application that displays a counter and a text input field. The application should demonstrate lifecycle callbacks and preserve the appropriate state when the device configuration changes.

Requirements

  1. Create an Activity with a TextView, an EditText, and an increment Button.
  2. Log the main lifecycle callbacks in Logcat.
  3. Use a ViewModel to preserve the counter across configuration changes.
  4. Use saved-state APIs for suitable lightweight custom UI values.
  5. Assign unique IDs to views so supported view-state restoration can work correctly.
  6. Rotate the device and verify that the counter and text behave as expected.
  7. Move the app to the background and return to it.
  8. Test process recreation where practical and confirm that important persisted information can be recovered.

Expected Outcome

The counter should remain available during configuration changes through the ViewModel. Lightweight saved values should restore when the saved-state mechanism applies. Information that must survive process death or the user's explicit dismissal of the screen should be stored persistently.

19. Troubleshooting Checklist

  • Values disappear after rotation: Check whether the values exist only in Activity properties. Consider a ViewModel and saved-state mechanism.
  • Values disappear after the app was in the background: The process may have been terminated. Use saved state or persistent storage as appropriate.
  • Callbacks appear in an unexpected order: Add Logcat messages to each callback and repeat a specific action.
  • Duplicate events occur: Check whether listeners or observers are registered more than once.
  • Memory leaks occur: Check long-lived references to Activity instances, views, or callbacks.
  • The application becomes slow during navigation: Move expensive operations off the main thread and keep callbacks short.
  • View text does not restore: Verify that the view has a unique ID and that custom state is handled correctly.

20. Interview Questions and Answers

Q1. What is the Android Activity lifecycle?

Answer: It is the sequence of states and callbacks an Activity passes through as it is created, becomes visible, enters the foreground, loses focus, stops, restarts, and is destroyed.

Q2. What is the purpose of onCreate()?

Answer: It initializes a new Activity instance, sets up the interface, and can restore small saved values when available.

Q3. What is the difference between onStart() and onResume()?

Answer: onStart() indicates that the Activity is visible, whereas onResume() indicates that it has entered the resumed state and is generally ready for interaction.

Q4. When is onPause() called?

Answer: It is called when an Activity loses its resumed state, such as when another Activity takes focus or the user navigates away.

Q5. What is the purpose of onStop()?

Answer: It indicates that the Activity is no longer visible. It is suitable for stopping work that is required only while the screen is visible.

Q6. Why should important data not be saved only in onDestroy()?

Answer: Android may terminate an app process without calling the Activity's onDestroy(). Important data should be saved earlier and stored persistently when required.

Q7. What is a Bundle?

Answer: A Bundle is a key-value container used to pass data between Android components and preserve small amounts of saved state.

Q8. What is the difference between ViewModel and saved instance state?

Answer: A ViewModel retains screen-related data across configuration changes while its scope remains alive. Saved instance state preserves small values for restoration after Activity recreation and certain system-initiated process-death scenarios.

Q9. Does a ViewModel survive process death?

Answer: No. A normal ViewModel stores data in memory. Use saved-state APIs and persistent storage when data must survive process death.

Q10. What is a configuration change?

Answer: It is a change in device or app configuration, such as orientation or screen size, that may cause Android to recreate an Activity.

Q11. What commonly happens when the user presses Home?

Answer: The Activity usually receives onPause() and then onStop() if it becomes fully hidden. The process may remain in memory or be terminated later.

Q12. How can lifecycle-related memory leaks be prevented?

Answer: Release resources at suitable lifecycle boundaries, avoid long-lived references to Activity objects, and prefer lifecycle-aware APIs.

21. Quick Revision Notes

  • onCreate(): initializes a new Activity instance.
  • onStart(): the Activity becomes visible.
  • onResume(): the Activity enters the resumed state.
  • onPause(): the Activity loses its resumed state.
  • onStop(): the Activity is no longer visible.
  • onRestart(): a stopped Activity is about to start again.
  • onDestroy(): the Activity instance is destroyed through normal lifecycle processing.
  • onSaveInstanceState(): saves lightweight transient state when requested by Android.
  • ViewModel: retains screen-related state across configuration changes within its scope.
  • SavedStateHandle: supports restoration of suitable lightweight ViewModel state.
  • Persistent storage: preserves important data beyond the lifetime of the Activity and process.
  • Never rely on onDestroy() as the only opportunity to save important data.

22. Conclusion

Managing Activity state and application lifecycle events is essential for developing reliable Android applications. A strong understanding of lifecycle callbacks helps developers initialize screens correctly, manage resources efficiently, preserve user progress, and respond properly to interruptions.

Use lifecycle callbacks for work that depends on visibility or foreground interaction, ViewModels for screen data that must survive configuration changes, saved-state mechanisms for lightweight transient values, and persistent storage for information that must outlive the application process. Combining these approaches makes Android applications more reliable during navigation, screen rotation, backgrounding, and system-managed process recreation.

23. Further Learning Resources

Previous Next
whatsapp